package cn.com.dcsgo.service.impl;

import cn.com.dcsgo.dto.BasketDTO;
import cn.com.dcsgo.dto.ShopInfoDTO;
import cn.com.dcsgo.dto.SkuDTO;
import cn.com.dcsgo.exception.BusinessException;
import cn.com.dcsgo.feign.ProdFeignClient;
import cn.com.dcsgo.feign.ShopFeignClient;
import cn.com.dcsgo.model.ShopCart;
import cn.com.dcsgo.model.ShopCartItem;
import cn.com.dcsgo.utils.AuthUtil;
import cn.com.dcsgo.vo.CartMoneyVO;
import cn.com.dcsgo.vo.CartVO;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.com.dcsgo.domain.Basket;
import cn.com.dcsgo.service.BasketService;
import cn.com.dcsgo.mapper.BasketMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 针对表【basket(购物车)】的数据库操作Service实现
 *
 * @author Dcsgo
 * @since 2025-11-14 15:09:22
 */
@Service
public class BasketServiceImpl extends ServiceImpl<BasketMapper, Basket>
        implements BasketService {

    @Resource
    private ShopFeignClient shopFeignClient;

    @Resource
    private ProdFeignClient prodFeignClient;

    @Override
    public Integer getProdTotal() {
        return baseMapper.getProdTotalByOpenId(AuthUtil.getOpenid());
    }

    @Override
    public boolean saveOrUpdate(BasketDTO basketDTO) {
        Integer prodTotal = getProdTotal();
        // 购物车中商品的总数不能超过100个
        String openid = AuthUtil.getOpenid();
        Basket oldData = baseMapper.selectOne(
                new LambdaQueryWrapper<Basket>()
                        .eq(Basket::getSkuId, basketDTO.getSkuId())
                        .eq(Basket::getOpenId, openid)
                        .eq(Basket::getShopId, basketDTO.getShopId())
        );
        // 购物车中没有当前商品
        if (oldData == null) {
            // 添加商品
            if (basketDTO.getProdCount() <= 0) {
                throw new BusinessException("商品数量不能小于0");
            } else if (basketDTO.getProdCount() + prodTotal > 100) {
                throw new BusinessException("此次添加商品数量过多！购物车中商品的总数不能超过100个");
            } else {
                Basket saveData = new Basket();
                BeanUtil.copyProperties(basketDTO, saveData);
                saveData.setOpenId(openid);
                return save(saveData);
            }
        } else {
            // 修改商品的购买数量
            int newProdCount = oldData.getProdCount() + basketDTO.getProdCount();
            if (newProdCount <= 0) {
                throw new BusinessException("修改后最终的商品数量不能小于等于0");
            } else if (newProdCount + prodTotal > 100) {
                throw new BusinessException("此次添加商品数量过多！购物车中商品的总数不能超过100个");
            } else {
                Basket updateData = new Basket();
                updateData.setBasketId(oldData.getBasketId());
                updateData.setProdCount(newProdCount);
                return updateById(updateData);
            }
        }
    }

    @Override
    public CartVO getCartVO(String openid) {
        CartVO cartVO = new CartVO();
        // 获取购物项信息（Basket）
        List<Basket> basketList = list(
                new LambdaQueryWrapper<Basket>()
                        .eq(Basket::getOpenId, openid)
                        .orderByDesc(Basket::getCreateTime)
        );
        if (basketList.isEmpty()) {
            return cartVO;
        }
        Map<Long, List<Basket>> basketShopIdMap = basketList.stream().collect(Collectors.groupingBy(Basket::getShopId));

        // TODO 多线程优化RPC时间
        // 获取店铺信息
        Set<Long> shopIds = basketList.stream().map(Basket::getShopId).collect(Collectors.toSet());
        List<ShopInfoDTO> shopInfoDTOList = shopFeignClient.getShopInfoDTOList(shopIds);
        ArrayList<ShopCart> shopCarts = new ArrayList<>(shopInfoDTOList.size());
        shopInfoDTOList.forEach(shopInfoDTO -> {
            ShopCart shopCart = new ShopCart();
            shopCart.setShopId(shopInfoDTO.getShopId());
            shopCart.setShopName(shopInfoDTO.getShopName());
            shopCarts.add(shopCart);
        });
        cartVO.setShopCarts(shopCarts);

        // 获取商品（SKU）信息
        Set<Long> skuIds = basketList.stream().map(Basket::getSkuId).collect(Collectors.toSet());
        List<SkuDTO> skuDTOList = prodFeignClient.getSkuDTOListBySkuIds(skuIds);
        Map<Long, SkuDTO> skuDTOMap = skuDTOList.stream().collect(Collectors.toMap(SkuDTO::getSkuId, skuDTO -> skuDTO));

        //组装商品项信息和商品（SKU信息）
        shopCarts.forEach(shopCart -> {
            List<Basket> baskets = basketShopIdMap.get(shopCart.getShopId());
            ArrayList<ShopCartItem> shopCartItems = new ArrayList<>(baskets.size());
            baskets.forEach(basket -> {
                ShopCartItem shopCartItem = new ShopCartItem();
                BeanUtil.copyProperties(basket, shopCartItem);
                SkuDTO skuDTO = skuDTOMap.get(basket.getSkuId());
                BeanUtil.copyProperties(skuDTO, shopCartItem, "shopId", "prodId", "skuId", "createTime");
                shopCartItems.add(shopCartItem);
            });
            shopCart.setShopCartItems(shopCartItems);
        });

        return cartVO;
    }

    @Override
    public CartMoneyVO getCartMoneyVO(String openid, List<Long> basketIds) {
        CartMoneyVO cartMoneyVO = new CartMoneyVO();
        if (CollectionUtils.isEmpty(basketIds)) {
            return cartMoneyVO;
        }
        List<Basket> basketList = listByIds(basketIds);
        if (basketList.isEmpty()) {
            return cartMoneyVO;
        }
        Set<Long> skuIds = basketList.stream().map(Basket::getSkuId).collect(Collectors.toSet());
        List<SkuDTO> skuDTOList = prodFeignClient.getSkuDTOListBySkuIds(skuIds);
        Map<Long, SkuDTO> skuDTOMap = skuDTOList.stream().collect(Collectors.toMap(SkuDTO::getSkuId, skuDTO -> skuDTO));
        // 目前没有优惠券等优惠功能，优惠金额写死为0
        BigDecimal subtractMoney = BigDecimal.ZERO;
        BigDecimal totalMoney = BigDecimal.ZERO;
        for (Basket basket : basketList) {
            Integer prodCount = basket.getProdCount();
            SkuDTO skuDTO = skuDTOMap.get(basket.getSkuId());
            totalMoney = totalMoney.add(skuDTO.getPrice().multiply(BigDecimal.valueOf(prodCount)));
        }
        BigDecimal transMoney = BigDecimal.valueOf(10);
        // 商品总价大于等于99免运费（包邮）
        if (totalMoney.compareTo(BigDecimal.valueOf(99)) >= 0) {
            transMoney = BigDecimal.ZERO;
        }
        BigDecimal finalMoney = totalMoney.subtract(subtractMoney).add(transMoney);
        cartMoneyVO.setTotalMoney(totalMoney);
        cartMoneyVO.setFinalMoney(finalMoney);
        cartMoneyVO.setTransMoney(transMoney);
        cartMoneyVO.setSubtractMoney(subtractMoney);
        return cartMoneyVO;
    }
}
